package rpcx

import (
	"context"
	"strings"

	"gitee.com/yanwc/gozero-utils/errx"
	"gitee.com/yanwc/gozero-utils/httpx"
	"gitee.com/yanwc/gozero-utils/jwtx"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

const (
	AuthorizationKey = "authorization"
)

// token 不强制传递token
func UserContextInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return handler(ctx, req)
	}

	token, ok := md[AuthorizationKey]
	if len(token) == 0 || !ok {
		return handler(ctx, req)
	}

	if !strings.Contains(token[0], "Bearer") {
		ctx = context.WithValue(ctx, httpx.NewRpcTokenKey(), token[0])
		return handler(ctx, req)
	}

	data := strings.Split(token[0], " ")
	if len(data) != 2 {
		return nil, errx.New(errx.TOKEN_PARSER, errx.WithMsgOption("Auth Format Error"))
	}

	ctx = context.WithValue(ctx, httpx.NewRpcTokenKey(), data[1])
	return handler(ctx, req)
}

// 获取并验证jwt token
func GetUserContextFromWithJwt[T any](ctx context.Context, secret string, uc *T) *errx.Error {
	token := ctx.Value(httpx.NewRpcTokenKey())
	if t, ok := token.(string); ok {
		err := jwtx.ParseToken(t, secret, uc)
		return errx.New(errx.TOKEN_PARSER, errx.WithErrorOption(err))
	} else {
		return errx.New(errx.TOKEN_PARSER)
	}
}

// 获取token
func GetToken(ctx context.Context) string {
	token := ctx.Value(httpx.NewRpcTokenKey())
	if t, ok := token.(string); ok {
		return t
	} else {
		return ""
	}
}
